package cz.pecinovsky.česky.oopnz._134_;
//Příliš žluťoučký kůň úpěl ďábelské ódy

import cz.pecinovsky.česky.oopnz._000_.Run;

import cz.pecinovsky.česky.oopnz.správce.IPosuvný;
import cz.pecinovsky.česky.oopnz.správce.Multipřesouvač;
import cz.pecinovsky.česky.oopnz.správce.Přesouvač;
import cz.pecinovsky.česky.oopnz.správce.SprávcePlátna;


import static cz.pecinovsky.česky.oopnz._134_.IModulový_134_    .IModulový;
import static cz.pecinovsky.česky.oopnz._134_.IOtočný_136_      .IOtočný;
import static cz.pecinovsky.česky.oopnz._134_.Otočný_136_       .Otočný;
import static cz.pecinovsky.česky.oopnz._134_.Okruh_134_        .Okruh;


//import static cz.pecinovsky.česky.oopnz._134_.TestUtility_134_  .TestUtility;
////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ Konec ignorovaného počátečního textu +++++
//%I+ =133c
//
//import správce.IO;
//import správce.IPosuvný;
//import správce.Pozice;
//import správce.Přesouvač;
//import správce.SprávcePlátna;
//
////import správce.*;
//%I-
//%I+ >=133x
//
//import cz.pecinovsky.česky.oopnz.správceplátna.IPosuvný;
//import cz.pecinovsky.česky.oopnz.správceplátna.Přesouvač;
//import cz.pecinovsky.česky.oopnz.správceplátna.SprávcePlátna;
//%I-
//%I+ >136
//import cz.pecinovsky.česky.oopnz.správceplátna.Multipřesouvač;
//%I-
//%A+ >=133x

import cz.pecinovsky.česky.oopnz.utility.IO;
import cz.pecinovsky.česky.oopnz.utility.Pozice;
//%A-
//%A+ >142

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
//%A-
//%X+ xxxxx Začátek přeskakovaného textu xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   Není - toto_je_nově_definovaná_třída
 *              Ttt v projektu Ppp
 * Následující: Prozatím není
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class TestUtility_134_
{    private TestUtility_134_() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- Konec přeskakovaného textu -----


/*******************************************************************************
 * Knihovní třída {@code TestUtility} obsahuje sbírku pomocných metod
 * používaných testovacími třídami objektů implementujících rozhraní
 * {@link IModulový}.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
public class TestUtility extends junit.framework.TestCase
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    private static final SprávcePlátna SP = SprávcePlátna.getInstance();



//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================

    /** Pozice, na níž se bude přesouvat objekt testovaný v metodě
     *  {@link #poziceVelikost(IModulový)}. */
    private static Pozice pozice;

    /** Velikost menšího z modulů, které se budou nastavovat objektu
     *  testovanému v metodě {@link #poziceVelikost(IModulový)}. */
    private static int malýModul;

    /** Velikost většího z modulů, které se budou nastavovat objektu
     *  testovanému v metodě {@link #poziceVelikost(IModulový)}. */
    private static int velkýModul;



//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================

    /***************************************************************************
     * Vyzkouší změny pozice a velikosti zadaného objektu;
     * parametry testu je třeba předem nastavit pomocí metody
     *
     * @param pozice    Pozice, na kterou se testovaný objekt přesune
     * @param malý      Malá velikost modulu, jež se testovanému objektu zadá
     * @param velký     Velká velikost modulu, jež se testovanému objektu zadá
     */
    public static void setPoziceModuly(Pozice pozice, int malý, int velký)
    {
        TestUtility.pozice = pozice;
        malýModul  = malý;
        velkýModul = velký;
    }



//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================
//%A+ >136

    /***************************************************************************
     * Vyčistí plátno, postaví malý okruh a objede jej zadaným otočným objektem.
     * Zakomentovaný příkaz umožňuje postavit a objíždět okruh kolem plátna.
     *
     * @param objekt Testovaný otočný objekt
     */
    public static void objeďOkruh(IOtočný objekt)
    {
        SP.odstraňVše();
        int k = SP.getKrok();
//        Okruh  okruh  = Okruh.elko(new Pozice(k,k));
        Okruh  okruh  = Okruh.čtverec(new Pozice(k,k));
        Otočný otočný = new Otočný(objekt);
        otočný.objížděj(okruh);


        IO.zpráva("Až se pokocháš, stiskni OK");
        Multipřesouvač.getInstance().zastavVše();
    }

//%A-

    /***************************************************************************
     * Vyzkouší změny pozice a velikosti zadaného objektu;
     * parametry testu je třeba předem nastavit pomocí metody
     *
     * @param objekt Testovaný objekt
     */
    public static void poziceVelikost(IModulový objekt)
    {
        poziceVelikost(objekt, pozice, malýModul, velkýModul);
    }


    /***************************************************************************
     * Vyzkouší změny pozice a velikosti zadaného objektu s použitím
     * zadaných parametrů.
     *
     * @param objekt    Testovaný objekt
     * @param pozice    Pozice, na kterou se testovaný objekt přesune
     * @param malý      Malá velikost modulu, jež se testovanému objektu zadá
     * @param velký     Velká velikost modulu, jež se testovanému objektu zadá
     */
    public static void poziceVelikost(IModulový objekt,
                                      Pozice pozice, int malý, int velký)
    {
        final int ms = 500;
        objekt.setPozice(pozice.x, pozice.y);
        IO.čekej(ms);
        objekt.setModul(velký);
        IO.čekej(ms);
        objekt.setModul(malý);
        IO.čekej(ms);
        SP.odstraň(objekt);
        IO.čekej(ms);
    }


    /***************************************************************************
     * Prohodí pozice zadaných objektů a nechá zkontrolovat,
     * zda si objekty své pozice doopravdy vyměnily.
     *
     * @param o1 První objekt
     * @param o2 Druhý objekt
     */
    public static void prohoďPoziceSKontrolou(IPosuvný o1, IPosuvný o2)
    {
        Přesouvač přesouvač = new Přesouvač(10);
        Pozice p1 = o1.getPozice();
        Pozice p2 = o2.getPozice();

        System.out.println("Výchozí: " + p1 + " <--> " + p2);

        přesouvač.přesunNa(p2, o1);
        přesouvač.přesunNa(p1, o2);

        System.out.println("Cílová:  " + o1.getPozice() +
                              " <--> " + o2.getPozice() + "\n");

        assertEquals(p1, o2.getPozice());
        assertEquals(p2, o1.getPozice());
    }

//%A+ >142

    /***************************************************************************
     * Seřadí objekty v seznamu podle velikosti modulu,
     * stejně velké objekty pak seřadí nejprve podle vodorovné souřadnice
     * a když mají i tu stejnou, tak podle svislé souřadnice;
     * výsledný seznam vytiskne na standardní výstup.
     *
     * @param seznam Seznam s řazenými objekty
     */
    public static void seřaďSeznam(List<IModulový> seznam)
    {
        Collections.sort(seznam, new CompModulXY());
        System.out.println("\nModulově a pozičně seřazené instance:");
        int i = 0;
        for (IModulový im : seznam) {
            System.out.println(++i + ".  " + im);
        }
    }

//%A-
//%A+ >143

    /***************************************************************************
     * Vytvoří nový seznam jako instanci třídy {@link ArrayList}
     * a naplní jej hodnotami zadanými jako parametry.
     *
     * @param pole  Hodnoty, jimiž bude vytvořený seznam inicializován
     * @return Nový seznam naplněný zadanými hodnotami
     */
    public static List<IModulový> newListIModulový(IModulový... pole)
    {
        List<IModulový> seznam = new ArrayList<IModulový>();
        for (IModulový im : pole) {
            seznam.add(im);
        }
        return seznam;
    }

//%A-


//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /** Soukromý konstruktor brání vytvoření instancí. */
    private TestUtility( String název ) {}

//== PŘÍPRAVA A ÚKLID PŘÍPRAVKU ================================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//%A+ >142

    private static class CompModulXY implements Comparator<IModulový>
    {
        /***********************************************************************
         * Porovná objekty podle velikosti jejich modulu, stejně velké objekty
         * pak nejprve podle vodorovné souřadnice (menší souřadnice dopředu)
         * a když mají i tu stejnou, tak podle svislé souřadnice
         * (opět menší souřadnice dopředu).
         *
         * @param o1  První z porovnávaných objektů
         * @param o2  Druhý z porovnávaných objektů
         * @return Výsledek porovnání
         */
        @Override
        public int compare(IModulový o1, IModulový o2)
        {
            //Má-li být o1 < o2, musí se vrátit záporné číslo
            //Větší má být před menším =>  (o1 < o2) <=> ((o2-o1) < 0)
            if (o1.getModul() != o2.getModul()) {
                return o2.getModul() - o1.getModul();
            } else {
                //U souřadnic se dopředu probojuje naopak ten menší, takže
                //Menší má být před větším =>  (o1 < o2) <=> ((o1-o2) < 0)
                Pozice p1 = o1.getPozice();
                Pozice p2 = o2.getPozice();
                if (p2.x != p1.x) {
                    return p1.x - p2.x;
                } else {
                    return p1.y - p2.y;
                }
            }
        }
    }



//%A-
//== VLASTNÍ TESTY =============================================================
//
//     /***************************************************************************
//      *
//      */
//     public void testXXX()
//     {
//     }
}

//%%-  ----- Začátek ignorovaného závěrečného textu -----
////////////////////////////////////////////////////////////////////////////////
//== TESTY A METODA MAIN =======================================================
//Není-li třída testovací, následující dvě metody se smažou
//%X+   Metoda připravená k vložení do testovacích tříd
     /** */
     public void testPřípravek() {}
//%X-


    /***************************************************************************
     * Třída, jejíž instance má na starosti úklid mezi jednotlivými testy,
     * který není možno zakomponovat do metody {@code tearDown()},
     * dokud nebudou studenti umět programovat.
     */
    private static class TearDown implements Run.ITD
    {
        /** {@inheritDoc} */
        @Override
        public void ukliď()
        {
//            Plátno.smažPlátno();
//            SprávcePlátna.getInstance().odstraňVše();
        }
    }


    /***************************************************************************
     * Testovací metoda.
     */
    public static void test()
    {
////Nejedná-li se o testovací třídu, celý blok lze smazat
//        junit.textui.TestRunner.run(suite());
//        junit.textui.TestRunner.run(new Třída("test"));
//        Run.tests(Test.class,
//                new TearDown(),
//                "testPřípravek",
//                "");
        System.exit(0);
    }
    /** @param args Parametry příkazového řádku - nepoužívané. */
    public static void main( String[] args )  {  test();  }
}
